// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// w [author] rhyme_lph
// q [email]  rhymelph@gmail.com
// P [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:file_picker/file_picker.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/entities/account_entity.dart';
import 'package:finance_app/src/entities/bank_reconciliation_entity.dart';
import 'package:finance_app/src/entities/ocr_attachment_entity.dart';
import 'package:finance_app/src/http_service/http_account_service.dart';
import 'package:finance_app/src/http_service/http_attachment_service.dart';
import 'package:finance_app/src/http_service/http_bank_reconciliations_service.dart';
import 'package:finance_app/src/router_gen/router_gen_providers.dart';
import 'package:finance_app/src/utils/date_time_utils.dart';
import 'package:finance_app/src/widgets/bottom_sheet/calendar_bottom_sheet.dart';
import 'package:finance_app/src/widgets/bottom_sheet/judge_bottom_sheet.dart';
import 'package:flutter/material.dart';
import 'package:r_datetime_picker/r_datetime_picker.dart';

class ReconcileAccountProvider extends BaseProvider<List<AccountEntity>> {
  String file;
  int fileId;

  AccountEntity currentAccount;

  DateTime openingDate = DateTime.now();
  DateTime closingDate = DateTime.now();

  TextEditingController statementBalanceController = TextEditingController();
  FocusNode statementBalanceFocusNode = FocusNode();

  bool isDestroy = false;

  @override
  Future get dataFuture => HttpAccountService.accountList();

  Future<void> _loadUnCheck(List<AccountEntity> dataList) async {
    data = dataList;
    BankReconciliationEntity orderEntity;
    await post(HttpBankReconciliationsService.checkBank(),
        autoHandler: AutoHandler.Toast, onSuccess: (result) {
      //如果有未完成的，自动跳转到对比页面
      orderEntity = getEntityFromResult<BankReconciliationEntity>(result);
    });
    if (orderEntity != null) {
      final account = dataList.firstWhere(
          (element) => element.id == orderEntity.accountId,
          orElse: () => null);
      currentAccount = account;
      openingDate =
          DateTimeUtils.toDateTime(account.nextOpeningDate, 'yyyy-MM-dd');
      closingDate = DateTime(openingDate.year, openingDate.month,
          RDatetimeUtils.getDaysInMonth(openingDate.year, openingDate.month));
      statementBalanceController.text = orderEntity.statementBalance;
      if (orderEntity != null) {
        isDestroy = false;
        // if (orderEntity.hasFile == 1) {
        //   await Routes.navigateTo(
        //       RouterGenProviders.bankReconciliationDetailWithFilePage,
        //       params: {
        //         'title':
        //             '${currentAccount.bankName} ${currentAccount.accountNumber ?? ''}',
        //         'bank': orderEntity,
        //         'closingDate': DateTimeUtils.formatGlobalDateTime(closingDate),
        //         'currentAccount': currentAccount,
        //       });
        // } else {
        await Routes.navigateTo(RouterGenProviders.reconcileAccountDetailPage,
            params: {
              'title':
                  '${currentAccount.bankName} ${currentAccount.accountNumber ?? ''}',
              'bank': orderEntity,
              'closingDate': DateTimeUtils.formatGlobalDateTime(closingDate),
              'currentAccount': currentAccount,
            });
        // }
        obtainContext?.call((context) {
          if (isDestroy == true) Navigator.of(context).pop();
        });
      }
    } else {
      //没有已创建的Data
    }
  }

  void onStart() {
    statementBalanceFocusNode.unfocus();
    final stateBalance = statementBalanceController.text;
    if (stateBalance.isEmpty) {
      showToast(S.current.please_enter_statement_balance);
      return;
    }
    obtainContext?.call((context) async {
      bool isSuccess = true;
      // if (file == null) {
      //   isSuccess = await showUploadBankRecordsJudgeBottomSheet(context);
      //   if (isSuccess == true) {
      //     onAddFile();
      //     return;
      //   } else {
      //     isSuccess = true;
      //   }
      // }
      if (isSuccess == true) {
        BankReconciliationEntity orderEntity;

        if (file != null) {
          await uploadFile();
        }

        await post(
            HttpAccountService.createBankReconciliations(
              accountId: currentAccount?.id,
              start_date:
                  DateTimeUtils.formatDateTime(openingDate, 'yyyy-MM-dd'),
              end_date: DateTimeUtils.formatDateTime(closingDate, 'yyyy-MM-dd'),
              statement_balance: num.parse(statementBalanceController.text),
              attachment_ids: fileId != null ? [fileId] : null,
            ),
            autoHandler: AutoHandler.Toast,
            loadingTip: S.current.loading, onSuccess: (result) {
          orderEntity = getEntityFromResult<BankReconciliationEntity>(result);
        });
        if (orderEntity != null) {
          fileId = null;
          file = null;
          isDestroy = false;
          // if (orderEntity.hasFile == 1) {
          //   await Routes.navigateTo(
          //       RouterGenProviders.bankReconciliationDetailWithFilePage,
          //       params: {
          //         'title':
          //             '${currentAccount.bankName} ${currentAccount.accountNumber ?? ''}',
          //         'bank': orderEntity,
          //         'closingDate':
          //             DateTimeUtils.formatGlobalDateTime(closingDate),
          //         'currentAccount': currentAccount,
          //       });
          // } else {
          await Routes.navigateTo(RouterGenProviders.reconcileAccountDetailPage,
              params: {
                'title':
                    '${currentAccount.bankName} ${currentAccount.accountNumber ?? ''}',
                'bank': orderEntity,
                'closingDate': DateTimeUtils.formatGlobalDateTime(closingDate),
                'currentAccount': currentAccount,
              });
          // }
          if (isDestroy == true) {
            Navigator.of(context).pop();
          }
        }
      }
    });
  }

  void onDeleteFile() {
    statementBalanceFocusNode.unfocus();
    file = null;
    update();
  }

  void onAddFile() async {
    statementBalanceFocusNode.unfocus();
    final result = await FilePicker.platform.pickFiles();
    if (result != null) {
      file = result.files.single.path;
      update();
    }
  }

  void onSelectAccount(AccountEntity value) {
    statementBalanceFocusNode.unfocus();
    if (currentAccount != value) {
      currentAccount = value;
      openingDate =
          DateTimeUtils.toDateTime(value.nextOpeningDate, 'yyyy-MM-dd');
      closingDate = DateTime(openingDate.year, openingDate.month,
          RDatetimeUtils.getDaysInMonth(openingDate.year, openingDate.month));
      update();
    }
  }

  void onChangeOpeningDate() {
    statementBalanceFocusNode.unfocus();
    obtainContext?.call((context) async {
      openingDate = await showCalendarBottomSheet(context, openingDate);
      update();
    });
  }

  void onChangeClosingDate() {
    statementBalanceFocusNode.unfocus();
    obtainContext?.call((context) async {
      closingDate = await showCalendarBottomSheet(context, closingDate);
      update();
    });
  }

  Future<void> uploadFile() async {
    obtainContext?.call((context) {
      BaseConfig.dialogBase
          .showLoadingDialog(context: context, text: S.current.loading);
    });

    await post(
        HttpAttachmentService.createAttachment(
          file,
        ), onSuccess: (result) {
      final data = getEntityFromResult<OcrAttachmentEntity>(result);
      fileId = data.id;
    });

    if (fileId == null) {
      showToast(S.current.file_upload_failure);
      obtainContext?.call((context) {
        Navigator.of(context).pop();
      });
      return null;
    }

    obtainContext?.call((context) {
      Navigator.of(context).pop();
    });
  }

  @override
  FutureOr<List<AccountEntity>> transformData(
      List<AccountEntity> d, bool isCache) async {
    await _loadUnCheck(d);
    return super.transformData(d, isCache);
  }
}
